package edu.sdjzu.exam.service.group.impl;


import edu.sdjzu.exam.domain.exam.ExamAssignment;
import edu.sdjzu.exam.domain.group.UserGroup;
import edu.sdjzu.exam.domain.group.UserGroupMember;
import edu.sdjzu.exam.dto.UserGroupCreateDTO;
import edu.sdjzu.exam.dto.UserGroupDTO;
import edu.sdjzu.exam.dto.UserGroupUpdateDTO;
import edu.sdjzu.exam.dto.AddUsersToGroupDTO;
import edu.sdjzu.exam.dto.RemoveUsersFromGroupDTO;
import edu.sdjzu.exam.domain.auth.User;
import edu.sdjzu.exam.mapper.UserMapper;

import edu.sdjzu.exam.mapper.exam.ExamAssignmentMapper;
import edu.sdjzu.exam.mapper.group.UserGroupMapper;
import edu.sdjzu.exam.mapper.group.UserGroupMemberMapper;
import edu.sdjzu.exam.service.group.UserGroupService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserGroupServiceImpl implements UserGroupService {

    private final UserGroupMapper userGroupMapper;
    private final UserGroupMemberMapper userGroupMemberMapper;
    private final UserMapper userMapper;
    private final ExamAssignmentMapper examAssignmentMapper;

    @Override
    @Transactional
    public Long createUserGroup(UserGroupCreateDTO createDTO) {
        UserGroup userGroup = new UserGroup();
        userGroup.setGroupName(createDTO.getGroupName());
        userGroupMapper.insertUserGroup(userGroup);
        return userGroup.getGroupId();
    }

    @Override
    public UserGroupDTO getUserGroup(Long groupId) {
        UserGroup userGroup = userGroupMapper.selectUserGroupById(groupId);
        if (userGroup == null) {
            throw new RuntimeException("用户组不存在");
        }

        UserGroupDTO dto = new UserGroupDTO();
        dto.setGroupId(userGroup.getGroupId());
        dto.setGroupName(userGroup.getGroupName());
        dto.setCreatedAt(userGroup.getCreatedAt());
        dto.setUpdatedAt(userGroup.getUpdatedAt());

        List<UserGroupMember> members = userGroupMemberMapper.selectMembersByGroupId(groupId);
        List<UserGroupDTO.UserDTO> memberDTOs = members.stream().map(member -> {
            User user = userMapper.findById(member.getUserId());
            if (user == null) {
                return null;
            }
            UserGroupDTO.UserDTO userDTO = new UserGroupDTO.UserDTO();
            userDTO.setUserId(user.getUserId());
            userDTO.setUsername(user.getUsername());
            userDTO.setEmail(user.getEmail());
            userDTO.setRealName(user.getRealname());
            return userDTO;
        }).filter(userDTO -> userDTO != null).collect(Collectors.toList());
        dto.setMembers(memberDTOs);

        return dto;
    }

    @Override
    @Transactional
    public void updateUserGroup(UserGroupUpdateDTO updateDTO) {
        UserGroup userGroup = userGroupMapper.selectUserGroupById(updateDTO.getGroupId());
        if (userGroup == null) {
            throw new RuntimeException("用户组不存在");
        }
        userGroup.setGroupName(updateDTO.getGroupName());
        userGroupMapper.updateUserGroup(userGroup);
    }

    @Override
    @Transactional
    public void deleteUserGroup(Long groupId) {
        UserGroup userGroup = userGroupMapper.selectUserGroupById(groupId);
        if (userGroup == null) {
            throw new RuntimeException("用户组不存在");
        }
        // 检查是否有考试安排引用该用户组
        List<ExamAssignment> assignments = examAssignmentMapper.selectExamAssignmentsByGroupId(groupId);
        if (!assignments.isEmpty()) {
            throw new RuntimeException("用户组已被考试安排引用，无法删除");
        }
        userGroupMemberMapper.deleteMembersByGroupId(groupId);
        userGroupMapper.deleteUserGroup(groupId);
    }

    @Override
    public List<UserGroupDTO> listUserGroupsByCreator() {
        // 假设用户组没有 created_by 字段，教师可查询所有用户组
        // 如果需要限制为教师创建的用户组，需添加 created_by 字段
        List<UserGroup> userGroups = userGroupMapper.selectAllUserGroups();
        return userGroups.stream().map(group -> {
            UserGroupDTO dto = new UserGroupDTO();
            dto.setGroupId(group.getGroupId());
            dto.setGroupName(group.getGroupName());
            dto.setCreatedAt(group.getCreatedAt());
            dto.setUpdatedAt(group.getUpdatedAt());

            List<UserGroupMember> members = userGroupMemberMapper.selectMembersByGroupId(group.getGroupId());
            List<UserGroupDTO.UserDTO> memberDTOs = members.stream().map(member -> {
                User user = userMapper.findById(member.getUserId());
                if (user == null) {
                    return null;
                }
                UserGroupDTO.UserDTO userDTO = new UserGroupDTO.UserDTO();
                userDTO.setUserId(user.getUserId());
                userDTO.setUsername(user.getUsername());
                userDTO.setEmail(user.getEmail());
                userDTO.setRealName(user.getRealname());
                return userDTO;
            }).filter(userDTO -> userDTO != null).collect(Collectors.toList());
            dto.setMembers(memberDTOs);

            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void addUsersToGroup(AddUsersToGroupDTO addDTO) {
        UserGroup userGroup = userGroupMapper.selectUserGroupById(addDTO.getGroupId());
        if (userGroup == null) {
            throw new RuntimeException("用户组不存在");
        }
        for (Long userId : addDTO.getUserIds()) {
            User user = userMapper.findById(userId);
            if (user == null) {
                throw new RuntimeException("用户ID " + userId + " 不存在");
            }
            // 检查是否已存在
            UserGroupMember existingMember = userGroupMemberMapper.selectUserGroupMember(addDTO.getGroupId(), userId);
            if (existingMember != null) {
                continue; // 跳过已存在的成员
            }
            UserGroupMember member = new UserGroupMember();
            member.setGroupId(addDTO.getGroupId());
            member.setUserId(userId);
            userGroupMemberMapper.insertUserGroupMember(member);
        }
    }

    @Override
    @Transactional
    public void removeUsersFromGroup(RemoveUsersFromGroupDTO removeDTO) {
        UserGroup userGroup = userGroupMapper.selectUserGroupById(removeDTO.getGroupId());
        if (userGroup == null) {
            throw new RuntimeException("用户组不存在");
        }
        for (Long userId : removeDTO.getUserIds()) {
            User user = userMapper.findById(userId);
            if (user == null) {
                throw new RuntimeException("用户ID " + userId + " 不存在");
            }
            userGroupMemberMapper.deleteUserGroupMember(removeDTO.getGroupId(), userId);
        }
    }
}